/**
 * Generali Solutions d'assurances - Tous droits réservés &copy; 2007 - 2010
 */
package fr.generali.accueilclient.commun.servlet;

import java.io.IOException;

import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

import fr.generali.accueilclient.commun.exception.AclAsposeException;
import fr.generali.accueilclient.commun.handler.AbstractAsposeHandler;

/**
 * Servlet permettant d'intercepter les appels à rediriger vers l'handler aspose.
 *
 * @see HttpServlet
 * @see Servlet
 * @see ApplicationContextAware
 */
@Component
public class AsposeServlet extends HttpServlet implements Servlet, ApplicationContextAware {
    /**
     * Serial Version UID
     */
    private static final long serialVersionUID = -8617290859892244791L;
    /**
     * Application context instance
     */
    private static ApplicationContext appCtx;
    /**
     * LOGGER variable
     */
    private static final Logger LOGGER = LoggerFactory.getLogger(AsposeServlet.class);
    /**
     * Le nom du paramètre d'initialisation de la servlet
     */
    private static final String HANDLER_PARAM_NAME = "handlerClassName";
    /**
     * ServletConfig variable
     */
    private ServletConfig config;
    
    /**
     * Constructor par défaut
     */
    public AsposeServlet() {
        super();
    }

    /**
     * Initialisation de la configuration
     * @param config Servlet configuration object
     * @throws ServletException exception relative à la servlet
     */
    public void init(ServletConfig config) throws ServletException {
        super.init();
        this.config = config;
    }

    /**
     *
     */
    public void destroy() {
        // Intentional empty method
    }

    public ServletConfig getServletConfig() {
        return config;
    }

    public String getServletInfo() {
        return "A Simple Servlet";
    }

    /**
     * doGet méthode.
     * @param request la requête
     * @param response la réponse
     * @throws ServletException exception servlet
     * @throws IOException exception IO
     */
    protected void doGet(HttpServletRequest request,
            HttpServletResponse response) throws ServletException, IOException {
        try {
            getAsposeHandler().handlerRequest(request, response);
        } catch (AclAsposeException ex) {
            throw new ServletException(ex.getMessage(), ex);
        }
    }

    /**
     * doPost méthode
     * @param arg0 argument
     * @param arg1 objet servlet response
     * @throws ServletException exception servlet
     * @throws IOException exception IO
     */
    protected void doPost(HttpServletRequest arg0, HttpServletResponse arg1)
        throws ServletException, IOException {
        this.doGet(arg0, arg1);
    }

    /**
     * Setter affectant l'application context
     * @param applicationContext l'objet représentant l'application context
     */
    public void setApplicationContext(ApplicationContext applicationContext) {
        appCtx = applicationContext;
    }

    /**
     * Retourne un handler aspose.
     *
     * @return AbstractAsposeHandler Handler aspose
     * @throws ServletException Servlet exception
     */
    private AbstractAsposeHandler getAsposeHandler() throws ServletException {
        AbstractAsposeHandler asposeHandler = null;
        try {
            // instanciation de la classe en utilisant la factory spring
            asposeHandler = (AbstractAsposeHandler) appCtx.getBean(
                            getClass().forName(getInitParameter(HANDLER_PARAM_NAME)));
            // instanciation de la classe par réflexion
            if (asposeHandler == null) {
                asposeHandler = (AbstractAsposeHandler) getClass().forName(
                        getInitParameter(HANDLER_PARAM_NAME)).newInstance();
            }
        } catch (ClassNotFoundException e) {
            LOGGER.error(e.getMessage(), e);
            throw new ServletException(e.getMessage(), e);
        } catch (InstantiationException e) {
            LOGGER.error(e.getMessage(), e);
            throw new ServletException(e.getMessage(), e);
        } catch (IllegalAccessException e) {
            LOGGER.error(e.getMessage(), e);
            throw new ServletException(e.getMessage(), e);
        }
        return asposeHandler;
    }
}